/**
 * @file thread6.c
 * @brief RS232透明转发通信线程实现
 * 
 * 该线程负责通过RS232透明转发模块与其他设备进行通信。主要功能包括：
 * 1. 初始化RS232串口接口（/dev/ttyS9，对应外部连接器COM口）
 * 2. 循环接收串口数据，支持超时机制
 * 3. 处理接收到的数据
 * 4. 发送处理后的数据
 * 5. 在程序退出时释放串口资源
 * 
 * @note 该线程预留用于与外部无线转发模块通信，具体协议待定
 * 
 * @author 伞控
 * @date 2023
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <pthread.h>
#include <stdint.h>
#include <ctype.h>
#include "thread6.h"
#include "uart_common.h"
#include "thread10.h"
#include "log_utils.h"
#include "log_modules.h"
#include "thread9.h" // 新增：获取温湿度、风速风向
#include "thread8.h" // 新增：获取INSPVAXA

// 模块名称定义
#define THREAD6_MODULE LOG_MODULE_RS232

// 辅助函数声明
static char* format_hex_string(const uint8_t *data, int length);
static char* format_ascii_string(const uint8_t *data, int length);
static void log_raw_received_data(const uint8_t *data, int length);
static void log_raw_sent_data(const uint8_t *data, int length);
static void log_protocol_parse_result(uint8_t addr, uint8_t func, uint32_t data_len, 
                                    const uint8_t *data, int parse_success, const char *error_info);

// 全局变量（补充定义）
static int g_rs232_fd = -1;                 // 串口文件描述符
static int g_thread_running = 1;            // 线程运行标志
static uint32_t g_host_id = 0;              // 主机号（从device_id中提取的数字部分）
static char g_host_id_ascii[HOST_ID_ASCII_LEN + 1] = "01"; // ASCII主机号后缀

// 协议常量定义（新增）
#define PROTO_START_CHAR ':'
#define PROTO_END_CR '\r'
#define PROTO_END_LF '\n'
#define PROTO_FUNC_TIME_SYNC 0x01    // 广播：时间同步
#define PROTO_FUNC_REQ_DATA  0x0a    // 点对点：请求
#define PROTO_FUNC_RSP_DATA  0x11    // 点对点：应答
// 前置声明：十六进制字符判定
static int is_hex_char(char c);

static int hex2byte(const char *p, uint8_t *out) {
	if (!is_hex_char(p[0]) || !is_hex_char(p[1])) return -1;
	int v = 0;
	for (int i = 0; i < 2; i++) {
		char c = p[i];
		v <<= 4;
		if (c >= '0' && c <= '9') v |= (c - '0');
		else if (c >= 'A' && c <= 'F') v |= (c - 'A' + 10);
		else v |= (c - 'a' + 10);
	}
	*out = (uint8_t)v;
	return 0;
}

static void byte2hex_upper(uint8_t v, char *out2) {
	static const char *hex = "0123456789ABCDEF";
	out2[0] = hex[(v >> 4) & 0x0F];
	out2[1] = hex[v & 0x0F];
}

static const uint8_t *skip_spaces(const uint8_t *p, const uint8_t *end) {
	while (p < end && (*p == ' ' || *p == '\t')) p++;
	return p;
}

// 十六进制字符判定（补充实现）
static int is_hex_char(char c) {
	return ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'));
}

// 解析一帧协议（:AA FF LL DATA\r\n），返回0成功，-1失败（新增）
static int parse_protocol_frame(const uint8_t *buf, int len,
						uint8_t *addr, uint8_t *func, uint32_t *data_len,
						const uint8_t **data_ptr, const uint8_t **frame_end) {
	if (len < 9 || buf[0] != PROTO_START_CHAR) return -1;
	const uint8_t *p = buf + 1;
	const uint8_t *end = buf + len;

	// 跳过空格，提取地址字段（2个ASCII字符）
	p = skip_spaces(p, end);
	if (p + 2 > end) return -1;
	
	// 直接提取地址的ASCII值，转换为数字
	if (p[0] < '0' || p[0] > '9' || p[1] < '0' || p[1] > '9') return -1;
	*addr = (p[0] - '0') * 10 + (p[1] - '0');
	p += 2;
	
	// 跳过空格，提取功能码字段（2个ASCII字符）
	p = skip_spaces(p, end);
	if (p + 2 > end) return -1;
	
	// 直接提取功能码的ASCII值，转换为数字
	if (p[0] < '0' || p[0] > '9' || p[1] < '0' || p[1] > '9') return -1;
	*func = (p[0] - '0') * 10 + (p[1] - '0');
	p += 2;
	
	// 跳过空格，提取长度字段（2个ASCII字符）
	p = skip_spaces(p, end);
	if (p + 2 > end) return -1;
	
	// 直接提取长度的ASCII值，转换为数字（支持十六进制格式）
	uint8_t len_high, len_low;
	
	// 处理高位
	if (p[0] >= '0' && p[0] <= '9') {
		len_high = p[0] - '0';
	} else if (p[0] >= 'A' && p[0] <= 'F') {
		len_high = p[0] - 'A' + 10;
	} else if (p[0] >= 'a' && p[0] <= 'f') {
		len_high = p[0] - 'a' + 10;
	} else {
		return -1;
	}
	
	// 处理低位
	if (p[1] >= '0' && p[1] <= '9') {
		len_low = p[1] - '0';
	} else if (p[1] >= 'A' && p[1] <= 'F') {
		len_low = p[1] - 'A' + 10;
	} else if (p[1] >= 'a' && p[1] <= 'f') {
		len_low = p[1] - 'a' + 10;
	} else {
		return -1;
	}
	
	*data_len = len_high * 16 + len_low;
	p += 2;
	
	// 跳过空格，定位数据开始位置
	p = skip_spaces(p, end);

	// 数据区从p开始，长度为data_len
	const uint8_t *data_start = p;
	const uint8_t *data_end = p + *data_len;
	
	// 检查数据区域是否超出缓冲区
	if (data_end > end) {
		LOG_DEBUG(LOG_TO_CONSOLE_ONLY, LOG_MODULE_RS232, 
			"协议数据区域超出缓冲区: 数据结束位置=%p, 缓冲区结束=%p", data_end, end);
		return -1;
	}
	
	// 查找行尾（第一个\r或\n）
	const uint8_t *q = data_end;
	for (const uint8_t *i = data_start; i < end; i++) {
		if (*i == PROTO_END_CR || *i == PROTO_END_LF) {
			q = i;
			break;
		}
	}
	
	// 设置输出参数
	*data_ptr = data_start;
	*frame_end = q + 1; // 指向\r或\n之后
	return 0;
}

// 解析时间字符串YYYYMMDDHHMMSSmmm（UTC），成功返回0（新增）
static int parse_utc_time_17(const uint8_t *data, int len, struct timeval *tv_out) {
	if (len != 17) return -1;
	int Y, M, D, h, m, s, ms;
	for (int i = 0; i < 17; i++) if (data[i] < '0' || data[i] > '9') return -1;
	if (sscanf((const char*)data, "%4d%2d%2d%2d%2d%2d%3d", &Y, &M, &D, &h, &m, &s, &ms) != 7) return -1;
	
	// 使用更兼容的方法设置时间
	char time_str[64];
	snprintf(time_str, sizeof(time_str), "%04d-%02d-%02d %02d:%02d:%02d", Y, M, D, h, m, s);
	
	// 使用 date 命令设置系统时间（更兼容）
	char cmd[128];
	snprintf(cmd, sizeof(cmd), "date -s '%s'", time_str);
	int ret = system(cmd);
	
	if (ret == 0) {
		LOG_INFO(LOG_TO_FILE, LOG_MODULE_RS232, "时间同步成功: %s", time_str);
		// 设置微秒部分
		tv_out->tv_sec = time(NULL);
		tv_out->tv_usec = ms * 1000;
		return 0;
	} else {
		LOG_WARN(LOG_TO_FILE, LOG_MODULE_RS232, "时间同步失败: %s", time_str);
		return -1;
	}
}

// 构造应答数据DATA:...（包含温湿度、风速风向、INSPVAXA主要字段）（新增）
static int build_data_value_payload(char *out, int out_size) {
	int n = 0;
	int remain = out_size;
	// 获取线程9数据
	anemometer_data_t wind = {0};
	temp_humid_data_t th = {0};
	(void)get_anemometer_data(&wind);
	(void)get_temp_humid_data(&th);
	// 获取线程8 INSPVAXA
	nav_inspvaxa_data_t nav = {0};
	(void)get_nav_inspvaxa_data(&nav);
	// 获取传感器快照（包含线程4和线程5的接近传感器状态）
	global_sensor_snapshot_t sensor_snapshot = {0};
	(void)get_sensor_snapshot(&sensor_snapshot);
	
	// 组装，控制总长度，尽量紧凑
	#define APPEND_FMT(fmt, ...) \
		do { \
			int wrote = snprintf(out + n, remain, fmt, __VA_ARGS__); \
			if (wrote < 0 || wrote >= remain) { \
				return n; \
			} \
			n += wrote; \
			remain -= wrote; \
		} while (0)

	APPEND_FMT("%s", "DATA:");
	// 温湿度与风
	APPEND_FMT("TEMP=%.1f,HUMID=%.1f,WSP=%.2f,WDR=%.0f", th.temperature, th.humidity, wind.wind_speed, wind.wind_direction);
	// 接近传感器状态（新增：线程4和线程5）
	APPEND_FMT(",PROX1=%s,PROX2=%s", 
		sensor_snapshot.prox1.sensor_state == 0 ? "Valid" : "Invalid",
		sensor_snapshot.prox2.sensor_state == 0 ? "Valid" : "Invalid");
	// INSPVAXA（精简字段名，完整覆盖主要与精度项，尽量缩短小数位）
	APPEND_FMT(",INSP=port=%s,week=%d,sec=%.3f,sol=%s,INS=%s,POS=%s,lat=%.6f,lon=%.6f,h=%.2f,und=%.2f,vn=%.2f,ve=%.2f,vu=%.2f,roll=%.2f,pitch=%.2f,yaw=%.2f",
			nav.port, nav.week_number, nav.week_seconds, nav.solution_type, nav.ins_status, nav.pos_status,
			nav.latitude, nav.longitude, nav.height, nav.undulation,
			nav.north_velocity, nav.east_velocity, nav.up_velocity, nav.roll, nav.pitch, nav.azimuth);
	APPEND_FMT(",sLat=%.3f,sLon=%.3f,sH=%.3f,sVn=%.3f,sVe=%.3f,sVu=%.3f,sR=%.3f,sP=%.3f,sY=%.3f,ext=%d,idle=%d",
			nav.lat_std, nav.lon_std, nav.height_std, nav.north_vel_std, nav.east_vel_std, nav.up_vel_std,
			nav.roll_std, nav.pitch_std, nav.azimuth_std, nav.extended_status, nav.update_time);
	return n;
	#undef APPEND_FMT
}

// 构造完整协议应答帧到tx_buffer，返回帧长度（新增）
static int build_protocol_response(uint8_t addr, uint8_t func, const char *data, int data_len,
							 uint8_t *tx_buffer, int tx_buffer_size) {
	// 预估最小空间
	if (tx_buffer_size < (1 + 2 + 1 + 2 + 1 + data_len + 2)) return -1;
	int n = 0;
	tx_buffer[n++] = PROTO_START_CHAR;
	char hex2[2];
	byte2hex_upper(addr, hex2); tx_buffer[n++] = hex2[0]; tx_buffer[n++] = hex2[1];
	tx_buffer[n++] = ' ';
	byte2hex_upper(func, hex2); tx_buffer[n++] = hex2[0]; tx_buffer[n++] = hex2[1];
	tx_buffer[n++] = ' ';
	// 长度字段使用2位HEX（符合协议设计文档）
	byte2hex_upper((uint8_t)data_len, hex2);
	tx_buffer[n++] = hex2[0]; tx_buffer[n++] = hex2[1];
	tx_buffer[n++] = ' ';
	memcpy(tx_buffer + n, data, data_len); n += data_len;
	tx_buffer[n++] = ' ';
	tx_buffer[n++] = PROTO_END_CR;
	tx_buffer[n++] = PROTO_END_LF;
	return n;
}

/**
 * @brief 初始化RS232串口
 * 
 * @param device 串口设备名
 * @param baudrate 波特率
 * @return 成功返回文件描述符，失败返回-1
 */
int rs232_init(const char *device, int baudrate) {
    // 使用新的UART通用模块初始化串口
    uart_config_t config = {
        .baudrate = baudrate,
        .data_bits = 8,
        .stop_bits = 1,
        .parity = 0,
        .flow_control = 0,
        .timeout_ms = 100,
        .buffer_size = 65536,
        .flags = UART_FLAG_RAW_MODE | UART_FLAG_LARGE_BUFFER
    };
    
    int fd = uart_init_device(device, UART_TYPE_RS232, &config);
    if (fd < 0) {
        LOG_ERROR(LOG_TO_FILE, THREAD6_MODULE, "打开串口设备失败: %s", strerror(errno));
        return -1;
    }
    
    LOG_INFO(LOG_TO_FILE, THREAD6_MODULE, "串口 %s 初始化成功，波特率: %d", device, baudrate);
    return fd;
}

/**
 * @brief 接收串口数据，支持超时
 * 
 * @param fd 串口文件描述符
 * @param buffer 接收缓冲区
 * @param buffer_size 缓冲区大小
 * @param timeout_sec 超时秒数
 * @param timeout_usec 超时微秒数
 * @return 实际接收的数据长度，超时返回0，错误返回-1
 */
int rs232_receive(int fd, uint8_t *buffer, int buffer_size, int timeout_sec, int timeout_usec) {
	fd_set readfds;
	struct timeval timeout;
	int ret, total_bytes = 0;
	
	// 检查参数
	if (fd < 0 || buffer == NULL || buffer_size <= 0) {
		return -1;
	}
	
	// 清空缓冲区
	memset(buffer, 0, buffer_size);
	
	// 设置超时
	timeout.tv_sec = timeout_sec;
	timeout.tv_usec = timeout_usec;
	
	// 循环读取数据，直到超时或缓冲区满
	while (total_bytes < buffer_size) {
		// 设置文件描述符集
		FD_ZERO(&readfds);
		FD_SET(fd, &readfds);
		
		// 等待数据可读或超时
		ret = select(fd + 1, &readfds, NULL, NULL, &timeout);
		
		if (ret == -1) {
			// 发生错误
			LOG_ERROR(LOG_TO_FILE, THREAD6_MODULE, "select错误: %s", strerror(errno));
			return -1;
		} else if (ret == 0) {
			// 超时，返回已读取的字节数
			return total_bytes;
		} else {
			// 数据可读
			if (FD_ISSET(fd, &readfds)) {
				ret = read(fd, buffer + total_bytes, buffer_size - total_bytes);
				
				if (ret < 0) {
					// 读取错误
					LOG_ERROR(LOG_TO_FILE, THREAD6_MODULE, "读取串口数据错误: %s", strerror(errno));
					return -1;
				} else if (ret == 0) {
					// 没有更多数据
					break;
				} else {
					// 成功读取数据
					total_bytes += ret;
					
					// 重置超时，确保每次读取后都有完整的超时时间
					timeout.tv_sec = timeout_sec;
					timeout.tv_usec = timeout_usec;
				}
			}
		}
	}
	
	/*
	// 记录接收到的原始数据
	if (total_bytes > 0) {
		log_raw_received_data(buffer, total_bytes);
	}
	*/
	return total_bytes;
}

/**
 * @brief 发送串口数据
 * 
 * @param fd 串口文件描述符
 * @param buffer 发送缓冲区
 * @param length 要发送的数据长度
 * @return 成功返回发送的字节数，失败返回-1
 */
int rs232_send(int fd, const uint8_t *buffer, int length) {
    // 检查参数
    if (fd < 0 || buffer == NULL || length <= 0) {
        return -1;
    }
    
    // 发送数据
    int ret = write(fd, buffer, length);
    if (ret < 0) {
        LOG_ERROR(LOG_TO_FILE, THREAD6_MODULE, "发送串口数据错误: %s", strerror(errno));
        return -1;
    }
    
    // 等待数据发送完成
    tcdrain(fd);
    
    // 记录发送的原始数据
    if (ret > 0) {
        log_raw_sent_data(buffer, ret);
    }
    
    return ret;
}

/**
 * @brief 处理接收到的串口数据（扩展：协议解析 + 兼容旧GET）
 */
void rs232_process_data(const uint8_t *rx_buffer, int rx_length, uint8_t *tx_buffer, int *tx_length) {
	// 检查参数
	if (rx_buffer == NULL || tx_buffer == NULL || tx_length == NULL || rx_length <= 0) {
		*tx_length = 0;
		return;
	}
	
	*tx_length = 0;
	int offset = 0;
	while (offset < rx_length) {
		// 查找一行（以\n结尾），若没有则用剩余全部
		int line_end = offset;
		while (line_end < rx_length && rx_buffer[line_end] != '\n') line_end++;
		int line_len = line_end - offset + ((line_end < rx_length && rx_buffer[line_end] == '\n') ? 1 : 0);
		if (line_len <= 0) break;
		const uint8_t *line = rx_buffer + offset;
		
		// 尝试协议解析
		if (line[0] == PROTO_START_CHAR) {
			uint8_t addr = 0, func = 0; uint32_t dlen = 0;
			const uint8_t *data_ptr = NULL, *frame_end = NULL;
			if (parse_protocol_frame(line, line_len, &addr, &func, &dlen, &data_ptr, &frame_end) == 0) {
				// 记录协议解析成功
				log_protocol_parse_result(addr, func, dlen, data_ptr, 1, NULL);
				
				// 记录收到的协议帧（INFO + 文件）
				LOG_INFO(LOG_TO_FILE, THREAD6_MODULE, "接收协议帧: addr=%02X func=%02X len=%u data=\"%.*s\"",
					addr, func, (unsigned)dlen, (int)dlen, (const char*)data_ptr);

				LOG_INFO(LOG_TO_FILE, THREAD6_MODULE, "本设备信息: addr=%02X func=%02X \"",
					(uint8_t)(get_thread6_host_id() & 0xFF), PROTO_FUNC_REQ_DATA);
				
				if(func == PROTO_FUNC_REQ_DATA) {
					LOG_INFO(LOG_TO_FILE, THREAD6_MODULE, "本设备信息2: addr=%02X func=%02X \"",
					(uint8_t)(get_thread6_host_id() & 0xFF), PROTO_FUNC_REQ_DATA);
				}

				// 广播时间同步
				if (addr == 0x00 && func == PROTO_FUNC_TIME_SYNC) {
					LOG_INFO(LOG_TO_FILE, THREAD6_MODULE, "接收广播时间同步: data=\"%.*s\"", (int)dlen, (const char*)data_ptr);
					struct timeval tv;
					if (parse_utc_time_17(data_ptr, dlen, &tv) == 0) {
						if (settimeofday(&tv, NULL) == 0) {
							LOG_INFO(LOG_TO_FILE, LOG_MODULE_RS232, "时间同步成功: %ld.%06ld UTC", (long)tv.tv_sec, (long)tv.tv_usec);
						} else {
							LOG_WARN(LOG_TO_FILE, LOG_MODULE_RS232, "时间同步失败: %s", strerror(errno));
						}
					} else {
						LOG_WARN(LOG_TO_FILE, LOG_MODULE_RS232, "时间同步解析失败(长度或格式错误)");
					}
					// 广播不应答
				} else if (func == PROTO_FUNC_REQ_DATA && addr == (uint8_t)(get_thread6_host_id() & 0xFF)) {
					// 点对点：GET_ALL_DATA
					int is_get_all = (dlen == 11 && strncmp((const char*)data_ptr, "GET_ALL_DATA", 11) == 0);
					if (is_get_all) {
						LOG_INFO(LOG_TO_FILE, LOG_MODULE_RS232, "接收数据请求(GET_ALL_DATA) 来自addr=%02X", addr);
						char payload[RS232_TX_BUFFER_SIZE];
						int payload_len = build_data_value_payload(payload, sizeof(payload));
						int frame_len = build_protocol_response(addr, PROTO_FUNC_RSP_DATA, payload, payload_len, tx_buffer, RS232_TX_BUFFER_SIZE);
						if (frame_len > 0) {
							*tx_length = frame_len;
							LOG_INFO(LOG_TO_FILE, LOG_MODULE_RS232, "发送数据应答: addr=%02X func=%02X len=%d payload_len=%d payload=\"%.*s\"",
								addr, PROTO_FUNC_RSP_DATA, frame_len, payload_len, payload_len, payload);
							return; // 单次处理发送一帧
						}
					}
				}
			} else {
				// 记录协议解析失败
				log_protocol_parse_result(0, 0, 0, NULL, 0, "协议格式错误");
				
				// 增强调试信息：分析失败原因
				LOG_DEBUG(LOG_TO_CONSOLE_ONLY, LOG_MODULE_RS232, 
					"协议解析失败分析: 数据长度=%d, 数据内容=\"%s\"", 
					line_len, format_ascii_string(line, line_len));
				
				// 尝试分析失败的具体原因
				if (line_len < 9) {
					LOG_DEBUG(LOG_TO_CONSOLE_ONLY, LOG_MODULE_RS232, 
						"失败原因: 数据长度不足，需要至少9字节，实际%d字节", line_len);
				} else if (line[0] != PROTO_START_CHAR) {
					LOG_DEBUG(LOG_TO_CONSOLE_ONLY, LOG_MODULE_RS232, 
						"失败原因: 起始符错误，期望':', 实际'%c'", line[0]);
				} else {
					// 尝试解析各个字段，找出具体失败位置
					const uint8_t *p = line + 1;
					const uint8_t *end = line + line_len;
					
					p = skip_spaces(p, end);
					if (p + 2 > end) {
						LOG_DEBUG(LOG_TO_CONSOLE_ONLY, LOG_MODULE_RS232, 
							"失败原因: 地址字段长度不足");
					} else if (!is_hex_char(p[0]) || !is_hex_char(p[1])) {
						LOG_DEBUG(LOG_TO_CONSOLE_ONLY, LOG_MODULE_RS232, 
							"失败原因: 地址字段格式错误，期望十六进制，实际'%c%c'", p[0], p[1]);
					} else {
						p += 2;
						p = skip_spaces(p, end);
						if (p + 2 > end) {
							LOG_DEBUG(LOG_TO_CONSOLE_ONLY, LOG_MODULE_RS232, 
								"失败原因: 功能码字段长度不足");
						} else if (!is_hex_char(p[0]) || !is_hex_char(p[1])) {
							LOG_DEBUG(LOG_TO_CONSOLE_ONLY, LOG_MODULE_RS232, 
								"失败原因: 功能码字段格式错误，期望十六进制，实际'%c%c'", p[0], p[1]);
						} else {
							p += 2;
							// 检查长度字段
							if (p + 2 > end) {
								LOG_DEBUG(LOG_TO_CONSOLE_ONLY, LOG_MODULE_RS232, 
									"失败原因: 长度字段长度不足");
							} else if (!is_hex_char(p[0]) || !is_hex_char(p[1])) {
								LOG_DEBUG(LOG_TO_CONSOLE_ONLY, LOG_MODULE_RS232, 
									"失败原因: 长度字段格式错误，期望十六进制，实际'%c%c'", p[0], p[1]);
							} else {
								// 解析长度字段，检查数据区域
								uint8_t d8;
								if (hex2byte((const char*)p, &d8) == 0) {
									uint32_t dlen = d8;
									p += 2;
									p = skip_spaces(p, end);
									
									if (p + dlen > end) {
										LOG_DEBUG(LOG_TO_CONSOLE_ONLY, LOG_MODULE_RS232, 
											"失败原因: 数据区域超出缓冲区，声明长度=%u，剩余空间=%td", 
											dlen, end - p);
									} else {
										LOG_DEBUG(LOG_TO_CONSOLE_ONLY, LOG_MODULE_RS232, 
											"失败原因: 数据长度不匹配或数据格式错误，声明长度=%u", dlen);
									}
								} else {
									LOG_DEBUG(LOG_TO_CONSOLE_ONLY, LOG_MODULE_RS232, 
										"失败原因: 长度字段解析失败，期望十六进制，实际'%c%c'", p[0], p[1]);
								}
							}
						}
					}
				}
			}
		}
		
		// 兼容旧逻辑：非协议或非匹配，则沿用原GET回显/数据
		if (line_len >= 4 && strncmp((const char*)line, "GET", 3) == 0) {
			LOG_INFO(LOG_TO_FILE, THREAD6_MODULE, "接收非协议GET请求: \"%.*s\"", line_len, (const char*)line);
			// 获取传感器数据快照（保持原有实现）
			global_sensor_snapshot_t sensor_snapshot;
			if (get_sensor_snapshot(&sensor_snapshot) == 0) {
				int json_len = snprintf((char*)tx_buffer, RS232_TX_BUFFER_SIZE,
					"{\"timestamp\":%ld,\"sensors\":{\"prox1\":{\"state\":%d,\"valid\":%s},\"prox2\":{\"state\":%d,\"valid\":%s},\"nav\":{\"lat\":%.6f,\"lon\":%.6f,\"alt\":%.2f,\"valid\":%s},\"rs485\":{\"wind_speed\":%.2f,\"temp\":%.2f,\"valid\":%s}}}",
					sensor_snapshot.timestamp,
					sensor_snapshot.prox1.sensor_state,
					atomic_load(&sensor_snapshot.prox1.is_valid) ? "true" : "false",
					sensor_snapshot.prox2.sensor_state,
					atomic_load(&sensor_snapshot.prox2.is_valid) ? "true" : "false",
					sensor_snapshot.navigation.latitude,
					sensor_snapshot.navigation.longitude,
					sensor_snapshot.navigation.altitude,
					atomic_load(&sensor_snapshot.navigation.is_valid) ? "true" : "false",
					sensor_snapshot.rs485.wind_speed,
					sensor_snapshot.rs485.temperature,
					atomic_load(&sensor_snapshot.rs485.is_valid) ? "true" : "false");
				if (json_len > 0 && json_len < RS232_TX_BUFFER_SIZE) {
					*tx_length = json_len;
					LOG_INFO(LOG_TO_FILE, THREAD6_MODULE, "发送非协议GET应答，长度=%d", json_len);
					return;
				} else {
					const char *error_msg = "{\"error\":\"Buffer overflow\"}";
					int error_len = strlen(error_msg);
					if (error_len < RS232_TX_BUFFER_SIZE) {
						strncpy((char*)tx_buffer, error_msg, RS232_TX_BUFFER_SIZE - 1);
						tx_buffer[RS232_TX_BUFFER_SIZE - 1] = '\0';
						*tx_length = error_len;
						LOG_INFO(LOG_TO_FILE, THREAD6_MODULE, "发送非协议GET错误应答，长度=%d", error_len);
						return;
					}
				}
			}
		}
		
		// 前进到下一行
		offset += (line_len > 0 ? line_len : 1);
	}

	// 未产生应答
	*tx_length = 0;
}

/**
 * @brief 关闭串口
 * 
 * @param fd 串口文件描述符
 */
void rs232_close(int fd) {
    if (fd >= 0) {
        close(fd);
        LOG_INFO(LOG_TO_FILE, THREAD6_MODULE, "串口已关闭");
    }
}

/**
 * @brief 从配置文件中解析设备ID并提取主机号
 * 
 * @param host_id 指向存储主机号的32位整型变量的指针
 * @return 成功返回0，失败返回-1
 */
int parse_device_config_host_id(uint32_t *host_id) {
	FILE *fp;
	char line[512];
	char *ptr, *value;
	char device_id[MAX_DEVICE_ID_LEN];
	int device_id_found = 0;

	if (host_id == NULL) {
		LOG_ERROR(LOG_TO_FILE, THREAD6_MODULE, "主机号指针为空");
		return -1;
	}

	fp = fopen(DEVICE_CONFIG_FILE, "r");
	if (fp == NULL) {
		LOG_ERROR(LOG_TO_FILE, THREAD6_MODULE, "无法打开配置文件 %s", DEVICE_CONFIG_FILE);
		return -1;
	}

	// 默认值
	*host_id = 1;  // 默认主机号为1
	memcpy(g_host_id_ascii, "01", HOST_ID_ASCII_LEN);
	g_host_id_ascii[HOST_ID_ASCII_LEN] = '\0';

	while (fgets(line, sizeof(line), fp)) {
		// 查找device_id
		ptr = strstr(line, "\"device_id\"");
		if (ptr && !device_id_found) {
			ptr = strchr(ptr + 11, ':');
			if (ptr) {
				ptr++;
				while (isspace(*ptr)) ptr++;
				
				if (*ptr == '"') {
					value = ++ptr;
					ptr = strchr(value, '"');
					if (ptr) {
						*ptr = '\0';
						strncpy(device_id, value, MAX_DEVICE_ID_LEN - 1);
						device_id[MAX_DEVICE_ID_LEN - 1] = '\0';
						device_id_found = 1;
					}
				}
			}
		}
	}
	
	fclose(fp);
	
	if (!device_id_found) {
		LOG_WARN(LOG_TO_FILE, THREAD6_MODULE, "未找到device_id，使用默认主机号: %u, ASCII后缀: %s", *host_id, g_host_id_ascii);
		return 0;
	}
	
	// 从device_id中提取数字部分
	// 例如：从"LDCICM001"中提取"001"并转换为数字1
	ptr = device_id;
	while (*ptr && !isdigit(*ptr)) {
		ptr++;
	}
	
	if (*ptr) {
		// 找到数字部分，转换为整数，同时生成ASCII后缀
		char *endptr;
		unsigned long temp_id = strtoul(ptr, &endptr, 10);
		
		// 计算数字段长度
		int digits_len = (int)(endptr - ptr);
		char suffix[HOST_ID_ASCII_LEN + 1];
		memset(suffix, '0', HOST_ID_ASCII_LEN);
		suffix[HOST_ID_ASCII_LEN] = '\0';
		
		if (digits_len > 0) {
			// 取最右侧HOST_ID_ASCII_LEN位，不足则左补'0'
			int copy_len = digits_len >= HOST_ID_ASCII_LEN ? HOST_ID_ASCII_LEN : digits_len;
			memcpy(suffix + (HOST_ID_ASCII_LEN - copy_len), endptr - copy_len, copy_len);
		}
		
		memcpy(g_host_id_ascii, suffix, HOST_ID_ASCII_LEN);
		g_host_id_ascii[HOST_ID_ASCII_LEN] = '\0';
		
		if (endptr != ptr && temp_id <= UINT32_MAX) {
			*host_id = (uint32_t)temp_id;
			LOG_INFO(LOG_TO_FILE, THREAD6_MODULE,
					"成功解析设备ID: %s，提取主机号: %u，ASCII后缀: %s", device_id, *host_id, g_host_id_ascii);
			return 0;
		} else {
			LOG_WARN(LOG_TO_FILE, THREAD6_MODULE,
					"设备ID %s 中数字部分无效，使用默认主机号: %u, ASCII后缀: %s", device_id, *host_id, g_host_id_ascii);
			return 0;
		}
	} else {
		LOG_WARN(LOG_TO_FILE, THREAD6_MODULE,
				"设备ID %s 中未找到数字部分，使用默认主机号: %u, ASCII后缀: %s", device_id, *host_id, g_host_id_ascii);
		return 0;
	}
}

/**
 * @brief 获取当前主机号
 * 
 * @return 当前主机号（32位无符号整型）
 */
uint32_t get_thread6_host_id(void) {
	return g_host_id;
}

// 新增：获取ASCII主机号后缀
const char* get_thread6_host_id_ascii(void) {
	return g_host_id_ascii;
}

/**
 * @brief 线程6主函数
 * 
 * @param arg 线程参数
 * @return void* 
 */
void* thread6_function(void* arg) {
	(void)arg;  // 标记参数为未使用
	uint8_t rx_buffer[RS232_RX_BUFFER_SIZE];
	uint8_t tx_buffer[RS232_TX_BUFFER_SIZE];
	int tx_length;
	
	LOG_INFO(LOG_TO_FILE, LOG_MODULE_RS232, "线程6启动: RS232串口通信");

	// 解析设备配置，获取主机号
	if (parse_device_config_host_id(&g_host_id) == 0) {
		LOG_INFO(LOG_TO_FILE, LOG_MODULE_RS232, "线程6主机号初始化成功: %u", g_host_id);
		LOG_INFO(LOG_TO_FILE, LOG_MODULE_RS232, "线程6 ASCII主机号后缀: %s", get_thread6_host_id_ascii());
	} else {
		LOG_ERROR(LOG_TO_FILE, LOG_MODULE_RS232, "线程6主机号初始化失败，使用默认值: %u, ASCII: %s", g_host_id, get_thread6_host_id_ascii());
	}

	// 初始化串口
	g_rs232_fd = rs232_init(RS232_DEVICE, RS232_BAUDRATE);
	if (g_rs232_fd < 0) {
		LOG_WARN(LOG_TO_FILE, LOG_MODULE_RS232, "初始化RS232串口失败，线程6将以模拟模式运行");
		g_rs232_fd = -1; // 标记为无效
	} else {
		LOG_INFO(LOG_TO_FILE, LOG_MODULE_RS232, "RS232串口初始化成功");
	}

	/*	
	 * 硬件测试：每1秒发送一次测试字符串
	 */
	/*
	while(1){
		const char *test_msg = "hello thread 6\r\n";
		int test_len = strlen(test_msg);
		if (rs232_send(g_rs232_fd, (const uint8_t*)test_msg, test_len) > 0) {
			LOG_INFO(LOG_TO_FILE, LOG_MODULE_RS232, "硬件测试：发送测试字符串成功: %s", test_msg);
		} else {
			LOG_WARN(LOG_TO_FILE, LOG_MODULE_RS232, "硬件测试：发送测试字符串失败");
		}
		sleep(1);
	}
	*/

	// 主循环
	while (g_thread_running) {
		if (g_rs232_fd >= 0) {
			// 串口可用时的正常处理
			// 接收数据，超时100ms
			int rx_length = rs232_receive(g_rs232_fd, rx_buffer, RS232_RX_BUFFER_SIZE,
							   RS232_TIMEOUT_SEC, RS232_TIMEOUT_USEC);

			LOG_INFO(LOG_TO_FILE, LOG_MODULE_RS232, "接收数据长度：%d, 数据：%s", rx_length, format_ascii_string(rx_buffer, rx_length));
			
			if (rx_length < 0) {
				// 接收错误
				LOG_WARN(LOG_TO_FILE, LOG_MODULE_RS232, "接收串口数据错误，重试...");
				sleep(1);
				continue;
			} else if (rx_length > 0) {
				LOG_DEBUG(LOG_TO_CONSOLE_ONLY, LOG_MODULE_RS232, "接收到数据: %d字节", rx_length);
				
				// 立即处理接收到的数据
				rs232_process_data(rx_buffer, rx_length, tx_buffer, &tx_length);
				
				// 发送响应数据
				if (tx_length > 0) {
					if (rs232_send(g_rs232_fd, tx_buffer, tx_length) > 0) {
						LOG_DEBUG(LOG_TO_CONSOLE_ONLY, LOG_MODULE_RS232, "发送响应数据成功: %d字节", tx_length);
					} else {
						LOG_WARN(LOG_TO_FILE, LOG_MODULE_RS232, "发送响应数据失败");
					}
				}
				
				// 处理完成后，短暂等待，避免CPU占用过高
				usleep(10000); // 等待10ms
			} else {
				LOG_DEBUG(LOG_TO_CONSOLE_ONLY, LOG_MODULE_RS232, "串口接收超时（100ms）");
			}
		} else {
			// 串口不可用时的模拟模式
			LOG_DEBUG(LOG_TO_CONSOLE_ONLY, LOG_MODULE_RS232, "串口不可用，线程6以模拟模式运行");
			LOG_INFO(LOG_TO_FILE, LOG_MODULE_RS232, "线程6模拟模式运行中 - 串口设备 %s 不可用，等待 %d 秒后重试", 
			         RS232_DEVICE, 5);
			sleep(5); // 每5秒输出一次状态信息
		}
	}
	
	// 关闭串口（如果已打开）
	if (g_rs232_fd >= 0) {
		rs232_close(g_rs232_fd);
		g_rs232_fd = -1;
	}
	
	LOG_INFO(LOG_TO_FILE, LOG_MODULE_RS232, "线程6退出");
	return NULL;
}

void thread6_stop(void) {
    LOG_INFO(LOG_TO_FILE, LOG_MODULE_RS232, "线程6停止中");
    g_thread_running = 0;
}

// ==================== 辅助函数实现 ====================

/**
 * @brief 将二进制数据格式化为十六进制字符串（用于日志输出）
 * 
 * @param data 二进制数据指针
 * @param length 数据长度
 * @return 格式化后的十六进制字符串指针
 */
static char* format_hex_string(const uint8_t *data, int length) {
    static char hex_buffer[2048]; // 静态缓冲区，足够大
    int pos = 0;
    
    if (data == NULL || length <= 0) {
        snprintf(hex_buffer, sizeof(hex_buffer), "<NULL>");
        return hex_buffer;
    }
    
    for (int i = 0; i < length && pos < sizeof(hex_buffer) - 3; i++) {
        pos += snprintf(hex_buffer + pos, sizeof(hex_buffer) - pos, "%02X ", data[i]);
    }
    
    // 去掉最后一个空格
    if (pos > 0 && hex_buffer[pos-1] == ' ') {
        hex_buffer[pos-1] = '\0';
    }
    
    return hex_buffer;
}

/**
 * @brief 将ASCII数据格式化为可读字符串（处理特殊字符）
 * 
 * @param data 二进制数据指针
 * @param length 数据长度
 * @return 格式化后的ASCII字符串指针
 */
static char* format_ascii_string(const uint8_t *data, int length) {
    static char ascii_buffer[1024];
    int pos = 0;
    
    if (data == NULL || length <= 0) {
        snprintf(ascii_buffer, sizeof(ascii_buffer), "<NULL>");
        return ascii_buffer;
    }
    
    for (int i = 0; i < length && pos < sizeof(ascii_buffer) - 2; i++) {
        if (isprint(data[i])) {
            ascii_buffer[pos++] = data[i];
        } else {
            pos += snprintf(ascii_buffer + pos, sizeof(ascii_buffer) - pos, "\\x%02X", data[i]);
        }
    }
    ascii_buffer[pos] = '\0';
    
    return ascii_buffer;
}

/**
 * @brief 记录原始接收数据到日志
 * 
 * @param data 接收到的数据
 * @param length 数据长度
 */
static void log_raw_received_data(const uint8_t *data, int length) {
    if (data == NULL || length <= 0) return;
    
    // 记录十六进制格式
    LOG_INFO(LOG_TO_FILE, LOG_MODULE_RS232, "RAW_RX: [%d bytes] %s", 
             length, format_hex_string(data, length));
    
    // 记录ASCII格式（如果数据主要是可打印字符）
    int printable_count = 0;
    for (int i = 0; i < length; i++) {
        if (isprint(data[i])) printable_count++;
    }
    
    if (printable_count > length * 0.8) { // 80%以上是可打印字符
        LOG_INFO(LOG_TO_FILE, LOG_MODULE_RS232, "RAW_RX_ASCII: [%d bytes] %s", 
                 length, format_ascii_string(data, length));
    }
}

/**
 * @brief 记录原始发送数据到日志
 * 
 * @param data 发送的数据
 * @param length 数据长度
 */
static void log_raw_sent_data(const uint8_t *data, int length) {
    if (data == NULL || length <= 0) return;
    
    // 记录十六进制格式
    LOG_INFO(LOG_TO_FILE, LOG_MODULE_RS232, "RAW_TX: [%d bytes] %s", 
             length, format_hex_string(data, length));
    
    // 记录ASCII格式（如果数据主要是可打印字符）
    int printable_count = 0;
    for (int i = 0; i < length; i++) {
        if (isprint(data[i])) printable_count++;
    }
    
    if (printable_count > length * 0.8) { // 80%以上是可打印字符
        LOG_INFO(LOG_TO_FILE, LOG_MODULE_RS232, "RAW_TX_ASCII: [%d bytes] %s", 
                 length, format_ascii_string(data, length));
    }
}

/**
 * @brief 记录协议解析结果到日志
 * 
 * @param addr 地址
 * @param func 功能码
 * @param data_len 数据长度
 * @param data 数据内容
 * @param parse_success 解析是否成功（1=成功，0=失败）
 * @param error_info 错误信息（解析失败时）
 */
static void log_protocol_parse_result(uint8_t addr, uint8_t func, uint32_t data_len, 
                                    const uint8_t *data, int parse_success, const char *error_info) {
    if (parse_success) {
        // 解析成功
        if (data != NULL && data_len > 0) {
            LOG_INFO(LOG_TO_FILE, LOG_MODULE_RS232, "PROTO_PARSE_OK: addr=0x%02X func=0x%02X len=%u data=\"%s\"", 
                     addr, func, data_len, format_ascii_string(data, data_len));
        } else {
            LOG_INFO(LOG_TO_FILE, LOG_MODULE_RS232, "PROTO_PARSE_OK: addr=0x%02X func=0x%02X len=%u data=\"<empty>\"", 
                     addr, func, data_len);
        }
    } else {
        // 解析失败
        if (data != NULL && data_len > 0) {
            LOG_INFO(LOG_TO_FILE, LOG_MODULE_RS232, "PROTO_PARSE_FAIL: data=\"%s\" error=\"%s\"", 
                     format_hex_string(data, data_len), error_info ? error_info : "未知错误");
        } else {
            LOG_INFO(LOG_TO_FILE, LOG_MODULE_RS232, "PROTO_PARSE_FAIL: data=\"<empty>\" error=\"%s\"", 
                     error_info ? error_info : "未知错误");
        }
    }
} 